import { DraftsStore } from '@/store/DraftsStore';
import { GlobalStore } from '@/store/GlobalStore';
import { useCallback, useMemo } from 'react';
import { v4 } from "uuid";
import { IDraftDetail, IDraftItem, get_draft, load_drafts, remove_draft, save_draft, save_draft_options } from "./draftsMgr";

export interface ICreateDraftOpts extends Omit<save_draft_options, 'draft_id' | 'pwd'> {
  draft_id?: save_draft_options['draft_id'];
  pwd?: save_draft_options['pwd'];
}
export interface ICreateDraft {
  (opts?: ICreateDraftOpts): Promise<IDraftItem>
}

export interface ISaveDraft {
  (opts: Omit<save_draft_options, 'pwd'>): Promise<IDraftItem>;
}
export interface IGetDraft {
  (draft_id: string, pwd?: string): Promise<IDraftDetail | null>
}
export interface IRemoveDraft {
  (draft_id: string): Promise<IDraftItem | undefined>
}
export interface IReloadDrafts {
  (): Promise<IDraftItem[]>
}

export interface IDrafts {
  saving: boolean;
  loading: boolean;
  list: IDraftItem[];
  reload: IReloadDrafts;
  save: ISaveDraft;
  remove: IRemoveDraft;
  create: ICreateDraft;
  get: IGetDraft;
}

export function useDrafts(): IDrafts {
  const [{ username }] = GlobalStore.useStore();
  const [{ loading, saving, list }, dispatch] = DraftsStore.useStore();
  const set_loading = useCallback((v: boolean) => dispatch({ type: 'set_loading', payload: v }), [dispatch])
  const set_saving = useCallback((v: boolean) => dispatch({ type: 'set_saving', payload: v }), [dispatch])
  const set_list = useCallback((v: IDraftItem[]) => dispatch({ type: 'set_list', payload: v }), [dispatch])

  const reload = useCallback<IReloadDrafts>(async () => {
    set_loading(true);
    const list = await load_drafts()
    set_list(list);
    set_loading(false);
    return list;
  }, [set_list, set_loading]);

  const save = useCallback<ISaveDraft>(async (opts) => {
    set_saving(true);
    const full_opts: save_draft_options = { ...opts, pwd: username }
    const ret = await save_draft(full_opts).finally(() => set_saving(false));
    await reload();
    return ret
  }, [reload, set_saving, username]);

  const remove = useCallback<IRemoveDraft>(async (draft_id) => {
    set_loading(true);
    const next_draft = await remove_draft(draft_id);
    if (next_draft) {
      set_loading(false);
      return next_draft;
    }
    const [item] = await reload();
    return item
  }, [reload, set_loading]);

  const create = useCallback<ICreateDraft>(async (opts) => {
    set_loading(true)
    const full_opts: save_draft_options = {
      ...opts,
      draft_id: opts?.draft_id ?? v4(),
      pwd: opts?.pwd ?? username,
    }
    const ret = await save(full_opts);
    await reload();
    return ret;
  }, [reload, save, set_loading, username]);

  const get = useCallback<IGetDraft>(async (draft_id, pwd = '') => {
    return get_draft(draft_id, username, pwd);
  }, [username]);

  return useMemo(() => ({
    saving,
    loading,
    list,
    reload,
    save,
    remove,
    create,
    get
  }), [
    saving,
    loading,
    list,
    reload,
    save,
    remove,
    create,
    get
  ]);
}
